using System;
using System.Collections;
using System.ComponentModel;
using System.IO;
using System.Reflection;
using System.Resources;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

[assembly: WebResource("CodeStory.WebControls.Resource.ComboBox.js", "application/x-javascript")]
[assembly: WebResource("CodeStory.WebControls.Resource.ComboBoxArrow.gif", "image/gif")]

namespace CodeStory.WebControls
{
	/// <summary>
	/// 
	/// </summary>
	[ToolboxData("<{0}:ComboBox runat=server></{0}:ComboBox>")]
	[ParseChildren(true, "Items")]
	[PersistChildren(false)]
	[DefaultProperty("ID")]
	[Designer(typeof(ComboBoxDesigner))]
	public class ComboBox : WebControl, INamingContainer, IPostBackDataHandler
	{
		private ComboItemCollection _items = new ComboItemCollection();
		//private string textboxID = string.Empty;
		private object dataSource;
		private bool _requiresDataBinding;
		private bool _preRendered;

		public ComboBox() : base("div") {
		}

		[Browsable(false)]
		public string Text {
			get { 
				object obj = ViewState["Text"];
				return obj == null ? string.Empty : (string)obj;
			}
			set { 
				ViewState["Text"] = value;
				if (ChildControlsCreated) {
					ITextControl t = FindControl(this.ClientID) as ITextControl;
					if (t == null) return;
					t.Text = value;
				}
			}
		}

		[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
		[Editor(typeof(System.ComponentModel.Design.CollectionEditor), typeof(System.Drawing.Design.UITypeEditor))]
		[PersistenceMode(PersistenceMode.InnerDefaultProperty)]
		public ComboItemCollection Items {
			get { return _items; }
		}

		[DefaultValue("")]
		public virtual string DataMember {
			get {
				object obj1 = this.ViewState["DataMember"];
				if (obj1 != null) {
					return (string)obj1;
				}
				return string.Empty;
			}
			set { this.ViewState["DataMember"] = value; }
		}

		[DefaultValue((string)null)]
		public object DataSource {
			get { return this.dataSource; }
			set {
				if (((value != null) && !(value is IListSource)) && !(value is IEnumerable)) {
					throw new ArgumentException("unvalid data source.", this.ID);
				}
				this.dataSource = value;
			}
		}

		[DefaultValue("")]
		public virtual string DataTextField {
			get {
				object obj = this.ViewState["DataTextField"];
				return obj == null ? string.Empty : (string)obj;
			}
			set { this.ViewState["DataTextField"] = value; }
		}

		[DefaultValue("")]
		public virtual string DataValueField {
			get {
				object obj = this.ViewState["DataValueField"];
				return obj == null ? string.Empty : (string)obj;
			}
			set { this.ViewState["DataValueField"] = value; }
		}

		public string ValueFormatString {
			get {
				object obj = ViewState["ValueFormatString"];
				return obj == null ? null : (string)obj;
			}
			set { ViewState["ValueFormatString"] = value; }
		}


		#region IPostBackDataHandler Members
		public void RaisePostDataChangedEvent() {
		}

		public bool LoadPostData(string postDataKey, System.Collections.Specialized.NameValueCollection postCollection) {
			Control c = FindControl(this.ClientID);
			string text = postCollection[c.UniqueID];
			if (!Text.Equals(text)) {
				Text = text;
				return true;
			}

			return false;
		}
		#endregion

		public void ClearSelection() {
			for (int i = 0; i < this.Items.Count; i++) {
				this.Items[i].Selected = false;
			}
		}

		public ComboItem FindByText(string text) {
			for (int i = 0; i < this.Items.Count; i++) {
				if (string.Compare(text, this.Items[i].Text, true) == 0) {
					return this.Items[i];
				}
			}
			return null;
		}

		protected bool RequiresDataBinding {
			get { return this._requiresDataBinding; }
			set {
				if (((value && this._preRendered) && ((this.Page != null))) && !this.Page.IsCallback) {
					this._requiresDataBinding = true;
					this.EnsureDataBound();
				} else {
					this._requiresDataBinding = value;
				}
			}
		}

		private void EnsureDataBound() {
			if (this.RequiresDataBinding) {
				this.DataBind();
			}
		}

		protected override void CreateChildControls() {
			//base.CreateChildControls();
			if (this.RequiresDataBinding) {
				EnsureDataBound();
			} else {
				CreateControlHierarchy(false);
			}
		}

		string script;
		private void CreateControlHierarchy(bool databound) {
			ChildControlsCreated = true;
			TextBox tb = new TextBox();
			Controls.Add(tb);
			//tb.ID = ID;
			tb.ID = this.ClientID;
			tb.Attributes.Add("onkeypress","javascript:TextBoxKeyPress();");
			tb.Text = Text;
			
			Image img = new Image();
			Controls.Add(img);
			img.ImageUrl = Page.ClientScript.GetWebResourceUrl(GetType(), "CodeStory.WebControls.Resource.ComboBoxArrow.gif");
			img.Attributes.Add("onclick","javascript:ToggleList();");
			Panel p = new Panel();
			Controls.Add(p);
			p.Style.Add(HtmlTextWriterStyle.Display, "none");
			ListBox list = new ListBox();
			p.Controls.Add(list);
			list.Attributes.Add("onclick","javascript:ListClick();");
			list.Attributes.Add("onblur","javascript:ListBlur();");
			list.Items.Clear();
			foreach (ComboItem i in Items) {
				ListItem item = new ListItem(i.Text,i.Value);
				item.Selected = i.Selected;
				list.Items.Add(item);
			}
			script = string.Format(@"var ComboBoxChildren = {{TextBox:""{0}"",Image:""{1}"",ListPanel:""{2}"",List:""{3}""}};",tb.ClientID,img.ClientID,p.ClientID,list.ClientID);
		}

		protected override void AddParsedSubObject(object obj) {
			if (obj is ComboItem) {
				this.Items.Add((ComboItem)obj);
			}
		}

		protected override void AddAttributesToRender(HtmlTextWriter writer) {
			writer.AddAttribute(HtmlTextWriterAttribute.Name, this.UniqueID);
			base.AddAttributesToRender(writer);
		}

		protected override void OnPreRender(EventArgs e) {
			_preRendered = true;
			Page.ClientScript.RegisterClientScriptBlock(GetType(), "Declaration", script,true);
			Page.ClientScript.RegisterClientScriptResource(typeof(DataSourceHelper), "CodeStory.WebControls.Resource.CodeStory.js");
			Page.ClientScript.RegisterClientScriptResource(GetType(), "CodeStory.WebControls.Resource.ComboBox.js");
			Page.RegisterRequiresPostBack(this);
			base.OnPreRender(e);
		}

		protected override void OnDataBinding(EventArgs e) {
			base.OnDataBinding(e);
			IEnumerable enumerable1 = DataSourceHelper.GetResolvedDataSource(this.DataSource, this.DataMember);
			if (enumerable1 != null) {
				this.Items.Clear();
				foreach (object obj1 in enumerable1) {
					ComboItem item = new ComboItem();
					if (this.DataTextField != string.Empty) {
						item.Text = DataBinder.GetPropertyValue(obj1, this.DataTextField, null);
					} else {
						item.Text = obj1.ToString();
					}
					if (this.DataValueField != string.Empty) {
						item.Value = DataBinder.GetPropertyValue(obj1,this.DataValueField,ValueFormatString);
					}
					this.Items.Add(item);
				}
			}
			CreateControlHierarchy(true);
		}


		protected override void TrackViewState() {
			base.TrackViewState();
			((IStateManager)this.Items).TrackViewState();
		}

		protected override object SaveViewState() {
			object obj1 = base.SaveViewState();
			object obj2 = ((IStateManager)this.Items).SaveViewState();
			if (obj1 == null && obj2 == null) {
				return null;
			}
			return new Pair(obj1, obj2);
		}

		protected override void LoadViewState(object savedState) {
			if (savedState != null) {
				Pair state = (Pair)savedState;
				base.LoadViewState(state.First);
				((IStateManager)this.Items).LoadViewState(state.Second);
			}
		}
	}
}